home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / util / dres.3 < prev    next >
Text File  |  1988-10-25  |  32KB  |  1,385 lines

  1. Path: xanth!nic.MR.NET!umn-d-ub!rutgers!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i018:  dres - an object-oriented resource library, Part03/03
  5. Message-ID: <9823@swan.ulowell.edu>
  6. Date: 25 Oct 88 00:56:26 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 1374
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
  12. Posting-number: Volume 2, Issue 18
  13. Archive-name: util/dres.3
  14.  
  15. # This is a shell archive.  Remove anything before this line
  16. # then unpack it by saving it in a file and typing "sh file"
  17. # (Files unpacked will be owned by you and have default permissions).
  18. # This archive contains the following files:
  19. #    README
  20. #    core/TODO
  21. #    core/funcs.reg
  22. #    core/libfuncs.h
  23. #    core/libtag.asm
  24. #    core/Makefile
  25. #    core/func.def
  26. #    core/library.c
  27. #    libref.c
  28. #
  29. if `test ! -s README`
  30. then
  31. echo "writing README"
  32. cat > README << '\Rogue\Monster\'
  33.  
  34. The makefile is in core.  CD into core and then 'make'.   Make will fist
  35. compile libref.c which is used to generate the link library and library
  36. function array.
  37.  
  38. \Rogue\Monster\
  39. else
  40.   echo "will not over write README"
  41. fi
  42. if [ `wc -c README | awk '{printf $1}'` -ne 163 ]
  43. then
  44. echo `wc -c README | awk '{print "Got " $1 ", Expected " 163}'`
  45. fi
  46. if `test ! -d core`
  47. then
  48.   mkdir core
  49.   echo "mkdir core"
  50. fi
  51. if `test ! -s core/TODO`
  52. then
  53. echo "writing core/TODO"
  54. cat > core/TODO << '\Rogue\Monster\'
  55.  
  56. add dos.library to list of libraries....
  57.  
  58. \Rogue\Monster\
  59. else
  60.   echo "will not over write core/TODO"
  61. fi
  62. if [ `wc -c core/TODO | awk '{printf $1}'` -ne 43 ]
  63. then
  64. echo `wc -c core/TODO | awk '{print "Got " $1 ", Expected " 43}'`
  65. fi
  66. if `test ! -s core/funcs.reg`
  67. then
  68. echo "writing core/funcs.reg"
  69. cat > core/funcs.reg << '\Rogue\Monster\'
  70.  
  71. #    Q interrupts
  72.  
  73. AFUNC=    OpenQInts        -
  74. AFUNC=    CloseQInts        A0
  75. AFUNC=    SetQPri         D0/D1
  76. AFUNC=    SetQVector        D0/D1/D2/D3/A0
  77. AFUNC=    NULL            -
  78. AFUNC=    NULL            -
  79. AFUNC=    NULL            -
  80. AFUNC=    NULL            -
  81.  
  82. #    List functions
  83.  
  84. AFUNC=    GetHead         A0
  85. AFUNC=    GetTail         A0
  86. AFUNC=    GetSucc         A0
  87. AFUNC=    GetPred         A0
  88. AFUNC=    GetHeadOff        D0/D1
  89. AFUNC=    GetTailOff        D0/D1
  90. AFUNC=    GetSuccOff        D0/D1
  91. AFUNC=    GetPredOff        D0/D1
  92. AFUNC=    EnqueueLong        D0/D1/D2/D4
  93. AFUNC=    EnqueueOffLong        D0/D1/D2/D3/D4
  94. AFUNC=    SearchFwdNode        D0/D1/A1
  95. AFUNC=    SearchRvsNode        D0/D1/A1
  96. AFUNC=    SearchFwdList        D0/D1/A1
  97. AFUNC=    SearchRvsList        D0/D1/A1
  98. AFUNC=    SearchFwdNodeOff    D0/D1/A0/A1
  99. AFUNC=    SearchRvsNodeOff    D0/D1/A0/A1
  100. AFUNC=    SearchFwdListOff    D0/D1/A0/A1
  101. AFUNC=    SearchRvsListOff    D0/D1/A0/A1
  102. AFUNC=    NULL            -
  103. AFUNC=    NULL            -
  104. AFUNC=    NULL            -
  105. AFUNC=    NULL            -
  106.  
  107. #    Memory functions
  108.  
  109. AFUNC=    BZero            D0/D1
  110. AFUNC=    BSet            D0/D1/A0
  111. AFUNC=    BMov            D0/D1/A0
  112. AFUNC=    BCmp            D0/D1/A0
  113. AFUNC=    NULL            -
  114. AFUNC=    NULL            -
  115. AFUNC=    NULL            -
  116. AFUNC=    NULL            -
  117.  
  118. #    Misc. Functions
  119.  
  120. AFUNC=    WildCmp         D0/D1
  121. AFUNC=    WaitMsg         A0
  122. AFUNC=    CheckMsg        A0
  123. AFUNC=    CheckPort        A0
  124. AFUNC=    LockAddr        A0
  125. AFUNC=    LockAddrB        D0/A0
  126. AFUNC=    UnLockAddr        A0
  127. AFUNC=    UnLockAddrB        D0/A0
  128. AFUNC=    DoSyncMsg        A0/A1
  129. AFUNC=    FindName2        D0/A0
  130.  
  131. #   placed in res.c
  132. CFUNC=    GetTaskData        D0/D1
  133. CFUNC=    FreeTaskData        D0
  134.  
  135. CFUNC=    DateToS         D0/D1/A0
  136. CFUNC=    SetFileDate        D0/D1
  137. CFUNC=    NULL            -
  138. CFUNC=    NULL            -
  139. CFUNC=    NULL            -
  140. CFUNC=    NULL            -
  141.  
  142. #    IPC functions
  143.  
  144. CFUNC= OpenIPC            D0/D1
  145. CFUNC= CloseIPC         D0
  146. CFUNC= SendIPC            D0/D1/D2/A0
  147. CFUNC= SendIPC2         D0/D1
  148. CFUNC= ReplyIPC         D0/D1/D2/A0
  149. CFUNC= FreeIPC            D0
  150. CFUNC= DoIPC2            D0/D1/D2/A0
  151. CFUNC= ParseCmd         D0/D1/D2/D3/D4/A0
  152. CFUNC= FreeParseCmd        D0
  153. CFUNC= NULL            D0
  154. CFUNC= NULL            -
  155. CFUNC= NULL            -
  156. CFUNC= NULL            -
  157.  
  158. #    Resource Library functions
  159.  
  160. \Rogue\Monster\
  161. else
  162.   echo "will not over write core/funcs.reg"
  163. fi
  164. if [ `wc -c core/funcs.reg | awk '{printf $1}'` -ne 1944 ]
  165. then
  166. echo `wc -c core/funcs.reg | awk '{print "Got " $1 ", Expected " 1944}'`
  167. fi
  168. if `test ! -s core/libfuncs.h`
  169. then
  170. echo "writing core/libfuncs.h"
  171. cat > core/libfuncs.h << '\Rogue\Monster\'
  172.  
  173. /*
  174.  * Machine Generated Library Vectors
  175.  */
  176.  
  177. #ifndef NULL
  178. #define NULL 0L
  179. #endif
  180.  
  181. extern long _LibOpen(), _LibClose(), _LibExpunge();
  182. extern long lOpenQInts();
  183. extern long lCloseQInts();
  184. extern long lSetQPri();
  185. extern long lSetQVector();
  186. extern long lGetHead();
  187. extern long lGetTail();
  188. extern long lGetSucc();
  189. extern long lGetPred();
  190. extern long lGetHeadOff();
  191. extern long lGetTailOff();
  192. extern long lGetSuccOff();
  193. extern long lGetPredOff();
  194. extern long lEnqueueLong();
  195. extern long lEnqueueOffLong();
  196. extern long lSearchFwdNode();
  197. extern long lSearchRvsNode();
  198. extern long lSearchFwdList();
  199. extern long lSearchRvsList();
  200. extern long lSearchFwdNodeOff();
  201. extern long lSearchRvsNodeOff();
  202. extern long lSearchFwdListOff();
  203. extern long lSearchRvsListOff();
  204. extern long lBZero();
  205. extern long lBSet();
  206. extern long lBMov();
  207. extern long lBCmp();
  208. extern long lWildCmp();
  209. extern long lWaitMsg();
  210. extern long lCheckMsg();
  211. extern long lCheckPort();
  212. extern long lLockAddr();
  213. extern long lLockAddrB();
  214. extern long lUnLockAddr();
  215. extern long lUnLockAddrB();
  216. extern long lDoSyncMsg();
  217. extern long lFindName2();
  218. extern long _lGetTaskData();
  219. extern long _lFreeTaskData();
  220. extern long _lDateToS();
  221. extern long _lSetFileDate();
  222. extern long _lOpenIPC();
  223. extern long _lCloseIPC();
  224. extern long _lSendIPC();
  225. extern long _lSendIPC2();
  226. extern long _lReplyIPC();
  227. extern long _lFreeIPC();
  228. extern long _lDoIPC2();
  229. extern long _lParseCmd();
  230. extern long _lFreeParseCmd();
  231.  
  232.  
  233. /*
  234.  * -30-6*X
  235.  */
  236.  
  237. long (*LibVectors[])() = {
  238.     _LibOpen, _LibClose, _LibExpunge, NULL,
  239.  
  240.     lOpenQInts       ,    /*  -30                        */
  241.     lCloseQInts      ,    /*  -36  A0                    */
  242.     lSetQPri         ,    /*  -42  D0/D1                 */
  243.     lSetQVector      ,    /*  -48  D0/D1/D2/D3/A0        */
  244.     NULL,
  245.     NULL,
  246.     NULL,
  247.     NULL,
  248.     lGetHead         ,    /*  -78  A0                    */
  249.     lGetTail         ,    /*  -84  A0                    */
  250.     lGetSucc         ,    /*  -90  A0                    */
  251.     lGetPred         ,    /*  -96  A0                    */
  252.     lGetHeadOff      ,    /*  -102  D0/D1                 */
  253.     lGetTailOff      ,    /*  -108  D0/D1                 */
  254.     lGetSuccOff      ,    /*  -114  D0/D1                 */
  255.     lGetPredOff      ,    /*  -120  D0/D1                 */
  256.     lEnqueueLong     ,    /*  -126  D0/D1/D2/D4           */
  257.     lEnqueueOffLong  ,    /*  -132  D0/D1/D2/D3/D4        */
  258.     lSearchFwdNode   ,    /*  -138  D0/D1/A1              */
  259.     lSearchRvsNode   ,    /*  -144  D0/D1/A1              */
  260.     lSearchFwdList   ,    /*  -150  D0/D1/A1              */
  261.     lSearchRvsList   ,    /*  -156  D0/D1/A1              */
  262.     lSearchFwdNodeOff,    /*  -162  D0/D1/A0/A1           */
  263.     lSearchRvsNodeOff,    /*  -168  D0/D1/A0/A1           */
  264.     lSearchFwdListOff,    /*  -174  D0/D1/A0/A1           */
  265.     lSearchRvsListOff,    /*  -180  D0/D1/A0/A1           */
  266.     NULL,
  267.     NULL,
  268.     NULL,
  269.     NULL,
  270.     lBZero           ,    /*  -210  D0/D1                 */
  271.     lBSet            ,    /*  -216  D0/D1/A0              */
  272.     lBMov            ,    /*  -222  D0/D1/A0              */
  273.     lBCmp            ,    /*  -228  D0/D1/A0              */
  274.     NULL,
  275.     NULL,
  276.     NULL,
  277.     NULL,
  278.     lWildCmp         ,    /*  -258  D0/D1                 */
  279.     lWaitMsg         ,    /*  -264  A0                    */
  280.     lCheckMsg        ,    /*  -270  A0                    */
  281.     lCheckPort       ,    /*  -276  A0                    */
  282.     lLockAddr        ,    /*  -282  A0                    */
  283.     lLockAddrB       ,    /*  -288  D0/A0                 */
  284.     lUnLockAddr      ,    /*  -294  A0                    */
  285.     lUnLockAddrB     ,    /*  -300  D0/A0                 */
  286.     lDoSyncMsg       ,    /*  -306  A0/A1                 */
  287.     lFindName2       ,    /*  -312  D0/A0                 */
  288.     _lGetTaskData    ,    /*  -318  D0/D1                 */
  289.     _lFreeTaskData   ,    /*  -324  D0                    */
  290.     _lDateToS        ,    /*  -330  D0/D1/A0              */
  291.     _lSetFileDate    ,    /*  -336  D0/D1                 */
  292.     NULL,
  293.     NULL,
  294.     NULL,
  295.     NULL,
  296.     _lOpenIPC        ,    /*  -366  D0/D1                 */
  297.     _lCloseIPC       ,    /*  -372  D0                    */
  298.     _lSendIPC        ,    /*  -378  D0/D1/D2/A0           */
  299.     _lSendIPC2       ,    /*  -384  D0/D1                 */
  300.     _lReplyIPC       ,    /*  -390  D0/D1/D2/A0           */
  301.     _lFreeIPC        ,    /*  -396  D0                    */
  302.     _lDoIPC2         ,    /*  -402  D0/D1/D2/A0           */
  303.     _lParseCmd       ,    /*  -408  D0/D1/D2/D3/D4/A0     */
  304.     _lFreeParseCmd   ,    /*  -414  D0                    */
  305.     NULL,
  306.     NULL,
  307.     NULL,
  308.     NULL,
  309.     (long (*)())-1
  310. };
  311.  
  312. \Rogue\Monster\
  313. else
  314.   echo "will not over write core/libfuncs.h"
  315. fi
  316. if [ `wc -c core/libfuncs.h | awk '{printf $1}'` -ne 4739 ]
  317. then
  318. echo `wc -c core/libfuncs.h | awk '{print "Got " $1 ", Expected " 4739}'`
  319. fi
  320. if `test ! -s core/libtag.asm`
  321. then
  322. echo "writing core/libtag.asm"
  323. cat > core/libtag.asm << '\Rogue\Monster\'
  324.  
  325.     ; Machine Generated File
  326.     ; Tags for library routines which are in C
  327.  
  328.     FAR    DATA
  329.  
  330.  
  331.         public _lGetTaskData
  332.         public __lGetTaskData
  333.  
  334. __lGetTaskData:
  335.         movem.l    D2/D3/A6,-(sp)
  336.         movem.l    D0/D1,-(sp)
  337.         bsr    _lGetTaskData
  338.         addq.l    #8,A7
  339.         movem.l    (sp)+,D2/D3/A6
  340.         rts
  341.  
  342.         public _lFreeTaskData
  343.         public __lFreeTaskData
  344.  
  345. __lFreeTaskData:
  346.         movem.l    D2/D3/A6,-(sp)
  347.         move.l    D0,-(sp)
  348.         bsr    _lFreeTaskData
  349.         addq.l    #4,A7
  350.         movem.l    (sp)+,D2/D3/A6
  351.         rts
  352.  
  353.         public _lDateToS
  354.         public __lDateToS
  355.  
  356. __lDateToS:
  357.         movem.l    D2/D3/A6,-(sp)
  358.         movem.l    D0/D1/A0,-(sp)
  359.         bsr    _lDateToS
  360.         add.w    #12,A7
  361.         movem.l    (sp)+,D2/D3/A6
  362.         rts
  363.  
  364.         public _lSetFileDate
  365.         public __lSetFileDate
  366.  
  367. __lSetFileDate:
  368.         movem.l    D2/D3/A6,-(sp)
  369.         movem.l    D0/D1,-(sp)
  370.         bsr    _lSetFileDate
  371.         addq.l    #8,A7
  372.         movem.l    (sp)+,D2/D3/A6
  373.         rts
  374.  
  375.         public _lOpenIPC
  376.         public __lOpenIPC
  377.  
  378. __lOpenIPC:
  379.         movem.l    D2/D3/A6,-(sp)
  380.         movem.l    D0/D1,-(sp)
  381.         bsr    _lOpenIPC
  382.         addq.l    #8,A7
  383.         movem.l    (sp)+,D2/D3/A6
  384.         rts
  385.  
  386.         public _lCloseIPC
  387.         public __lCloseIPC
  388.  
  389. __lCloseIPC:
  390.         movem.l    D2/D3/A6,-(sp)
  391.         move.l    D0,-(sp)
  392.         bsr    _lCloseIPC
  393.         addq.l    #4,A7
  394.         movem.l    (sp)+,D2/D3/A6
  395.         rts
  396.  
  397.         public _lSendIPC
  398.         public __lSendIPC
  399.  
  400. __lSendIPC:
  401.         movem.l    D2/D3/A6,-(sp)
  402.         movem.l    D0/D1/D2/A0,-(sp)
  403.         bsr    _lSendIPC
  404.         add.w    #16,A7
  405.         movem.l    (sp)+,D2/D3/A6
  406.         rts
  407.  
  408.         public _lSendIPC2
  409.         public __lSendIPC2
  410.  
  411. __lSendIPC2:
  412.         movem.l    D2/D3/A6,-(sp)
  413.         movem.l    D0/D1,-(sp)
  414.         bsr    _lSendIPC2
  415.         addq.l    #8,A7
  416.         movem.l    (sp)+,D2/D3/A6
  417.         rts
  418.  
  419.         public _lReplyIPC
  420.         public __lReplyIPC
  421.  
  422. __lReplyIPC:
  423.         movem.l    D2/D3/A6,-(sp)
  424.         movem.l    D0/D1/D2/A0,-(sp)
  425.         bsr    _lReplyIPC
  426.         add.w    #16,A7
  427.         movem.l    (sp)+,D2/D3/A6
  428.         rts
  429.  
  430.         public _lFreeIPC
  431.         public __lFreeIPC
  432.  
  433. __lFreeIPC:
  434.         movem.l    D2/D3/A6,-(sp)
  435.         move.l    D0,-(sp)
  436.         bsr    _lFreeIPC
  437.         addq.l    #4,A7
  438.         movem.l    (sp)+,D2/D3/A6
  439.         rts
  440.  
  441.         public _lDoIPC2
  442.         public __lDoIPC2
  443.  
  444. __lDoIPC2:
  445.         movem.l    D2/D3/A6,-(sp)
  446.         movem.l    D0/D1/D2/A0,-(sp)
  447.         bsr    _lDoIPC2
  448.         add.w    #16,A7
  449.         movem.l    (sp)+,D2/D3/A6
  450.         rts
  451.  
  452.         public _lParseCmd
  453.         public __lParseCmd
  454.  
  455. __lParseCmd:
  456.         movem.l    D2/D3/A6,-(sp)
  457.         movem.l    D0/D1/D2/D3/D4/A0,-(sp)
  458.         bsr    _lParseCmd
  459.         add.w    #24,A7
  460.         movem.l    (sp)+,D2/D3/A6
  461.         rts
  462.  
  463.         public _lFreeParseCmd
  464.         public __lFreeParseCmd
  465.  
  466. __lFreeParseCmd:
  467.         movem.l    D2/D3/A6,-(sp)
  468.         move.l    D0,-(sp)
  469.         bsr    _lFreeParseCmd
  470.         addq.l    #4,A7
  471.         movem.l    (sp)+,D2/D3/A6
  472.         rts
  473. \Rogue\Monster\
  474. else
  475.   echo "will not over write core/libtag.asm"
  476. fi
  477. if [ `wc -c core/libtag.asm | awk '{printf $1}'` -ne 2290 ]
  478. then
  479. echo `wc -c core/libtag.asm | awk '{print "Got " $1 ", Expected " 2290}'`
  480. fi
  481. if `test ! -s core/Makefile`
  482. then
  483. echo "writing core/Makefile"
  484. cat > core/Makefile << '\Rogue\Monster\'
  485.  
  486. #   Makefile for DRES.LIBRARY,        AZTEC C 3.6a
  487. #
  488. #   NOTE:   You must have previously create the directory 'local' in your
  489. #        C include's directory and placed the distribution include/local
  490. #        directory there.  The libref program must also have been compiled
  491.  
  492. SYMS=    include:symbols.m
  493. SYMC=    include:local/makesymbols.c
  494. CFLAGS= +BCDLp +I$(SYMS)
  495. LREXE=    srcc:libref
  496.  
  497. SRC0=    library.c
  498. SRC1=    libtag.asm
  499. SRC2=    /src/misc.c
  500. SRC3=    /src/qint.asm
  501. SRC4=    /src/lists.asm
  502. SRC5=    /src/mem.asm
  503. SRC6=    /src/timedate.c
  504. SRC7=    /src/ipc.c
  505. SRC8=    /src/res.c
  506.  
  507. OBJ0=    vd0:library.o
  508. OBJ1=    vd0:libtag.o
  509. OBJ2=    vd0:misc.o
  510. OBJ3=    vd0:qint.o
  511. OBJ4=    vd0:lists.o
  512. OBJ5=    vd0:mem.o
  513. OBJ6=    vd0:timedate.o
  514. OBJ7=    vd0:ipc.o
  515. OBJ8=    vd0:res.o
  516.  
  517. OBJS=    $(OBJ0) $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(OBJ5) $(OBJ6) $(OBJ7)
  518.  
  519. all:  $(SYMS) $(LREXE) hlib $(OBJS)
  520.     ln    +Q $(OBJS) -ldres -lcl32 -o libs:dres.library
  521.  
  522. hlib:
  523.     libref
  524.     assign this: /core
  525.     cd ram:
  526.     make
  527.     cd this:
  528.     assign this:
  529.  
  530. $(OBJ0): $(SRC0)
  531.     cc    $(CFLAGS) $(SRC0) -o $(OBJ0)
  532.  
  533. $(OBJ1): $(SRC1)
  534.     as    $(SRC1) -o $(OBJ1)
  535.  
  536. $(OBJ2): $(SRC2)
  537.     cc    $(CFLAGS) $(SRC2) -o $(OBJ2)
  538.  
  539. $(OBJ3): $(SRC3)
  540.     as    $(SRC3) -o $(OBJ3)
  541.  
  542. $(OBJ4): $(SRC4)
  543.     as    $(SRC4) -o $(OBJ4)
  544.  
  545. $(OBJ5): $(SRC5)
  546.     as    $(SRC5) -o $(OBJ5)
  547.  
  548. $(OBJ6): $(SRC6)
  549.     cc $(CFLAGS) $(SRC6) -o $(OBJ6)
  550.  
  551. $(OBJ7): $(SRC7)
  552.     cc $(CFLAGS) $(SRC7) -o $(OBJ7)
  553.  
  554. $(OBJ8): $(SRC8)
  555.     cc $(CFLAGS) $(SRC8) -o $(OBJ8)
  556.  
  557. $(SYMS):    $(SYMC)
  558.     make -f include:local/Makefile
  559.  
  560. $(LREXE):   /libref.c
  561.     cc +L +I$(SYMS) /libref.c -o T:libref.o
  562.     ln +Q T:libref.o -lsup32 -lc32 -o $(LREXE)
  563.     delete T:libref.o
  564.  
  565. \Rogue\Monster\
  566. else
  567.   echo "will not over write core/Makefile"
  568. fi
  569. if [ `wc -c core/Makefile | awk '{printf $1}'` -ne 1591 ]
  570. then
  571. echo `wc -c core/Makefile | awk '{print "Got " $1 ", Expected " 1591}'`
  572. fi
  573. if `test ! -s core/func.def`
  574. then
  575. echo "writing core/func.def"
  576. cat > core/func.def << '\Rogue\Monster\'
  577.  
  578. ;   Run Time Library Function definition file
  579. ;
  580. ;   -Generate function table for MakeLibrary in C
  581. ;   -Generate tags in assembly for C
  582.  
  583. 1=  libfuncs.h
  584. 2=  ram:
  585. 3=  libtag.asm
  586. 4=  DResBase
  587. 5=  comp:clib/dres.lib
  588.  
  589. funcs.reg
  590.  
  591. \Rogue\Monster\
  592. else
  593.   echo "will not over write core/func.def"
  594. fi
  595. if [ `wc -c core/func.def | awk '{printf $1}'` -ne 224 ]
  596. then
  597. echo `wc -c core/func.def | awk '{print "Got " $1 ", Expected " 224}'`
  598. fi
  599. if `test ! -s core/library.c`
  600. then
  601. echo "writing core/library.c"
  602. cat > core/library.c << '\Rogue\Monster\'
  603.  
  604. /*
  605.  *  LIBRARY.C
  606.  *
  607.  *  Example fully working library for Aztec C ... with comments (which is
  608.  *  a miracle in itself).   By Matthew Dillon.    PUBLIC DOMAIN.
  609.  *
  610.  *  Aztec Compile with +BCDLp
  611.  *        +B    No startup reference
  612.  *        +C    Large code
  613.  *        +D    Large data
  614.  *        +L    32 bit Integers
  615.  *        +p    compatibility mode  (D2/D3 preserved)
  616.  *
  617.  *  Since Original release, the following has been fixed:
  618.  *    -slight bug in LibClose() .. did not expunge library if DELEXP set
  619.  *     on final close.  (thanks to Rico Mariani for finding the bug)
  620.  *    -Now uses MakeLibrary call rather than a hardwired Library structure.
  621.  */
  622.  
  623. #define NULL 0L
  624.  
  625. typedef struct Library    LIB;
  626.  
  627. extern LIB *MakeLibrary();
  628.  
  629. #define VERSION     1        /*    NOTE!  String in dc.b below must also be */
  630. #define REVISION    3        /*           Changed!              */
  631.  
  632. #asm
  633. VERSION     equ     1
  634.  
  635.     ;   RLIB.ASM
  636.     ;
  637.     ;   Run-time library tag
  638.  
  639.         FAR     data
  640.  
  641.         public  _CInit
  642.         public  _LibOpen
  643.         public  _LibClose
  644.         public  _LibExpunge
  645.  
  646. Start:        clr.l   D0
  647.         rts
  648.  
  649. InitDesc:   dc.w    $4AFC    ;RTC_MATCHWORD
  650.         dc.l    InitDesc    ;Pointer to beginning
  651.         dc.l    EndCode    ;Note sure it matters
  652.         dc.b    0        ;flags (NO RTF_AUTOINIT)
  653.         dc.b    VERSION    ;version
  654.         dc.b    9        ;NT_LIBRARY
  655.         dc.b    0        ;priority (doesn't matter)
  656.         dc.l    _Libname    ;Name of library
  657.         dc.l    _Libid    ;ID string (note CR-LF at end)
  658.         dc.l    Init    ;Pointer to init routine
  659.  
  660. _Libname:   dc.b    "dres.library",0
  661. _Libid:     dc.b    "dres.library 1.3 (29 Sep 1988)",13,10,0
  662. EndCode:
  663.  
  664. Init:        move.l  A6,-(sp)    ;Must save A6
  665.         move.l  A0,-(sp)    ;Segment list
  666.         jsr     _CInit
  667.         addq.l  #4,sp
  668.         move.l  (sp)+,A6
  669.         rts
  670.  
  671. cifc        macro
  672.         move.l  D0,-(sp)    ;Make a C call and save A6 to boot
  673.         move.l  A6,-(sp)
  674.         jsr     \1
  675.         move.l  (sp)+,A6
  676.         addq.l  #4,sp
  677.         rts
  678.         endm
  679.  
  680. __LibOpen:    cifc    _LibOpen
  681. __LibClose:    cifc    _LibClose
  682. __LibExpunge:    cifc    _LibExpunge
  683.  
  684. #endasm
  685.  
  686. extern char Libname[1];
  687. extern char Libid[1];
  688.  
  689. LIB  *Lib, *DResBase;         /*  Library Base pointer     */
  690. long Seglist;            /*  Save the DOS seglist    */
  691.  
  692.  
  693. /*
  694.  *    The Initialization routine is given only a seglist pointer.  Since
  695.  *    we are NOT AUTOINIT we must construct and add the library ourselves
  696.  *    and return either NULL or the library pointer.  Exec has Forbid()
  697.  *    for us during the call.
  698.  *
  699.  *    If you have an extended library structure you must specify the size
  700.  *    of the extended structure in MakeLibrary().
  701.  */
  702.  
  703. #include "libfuncs.h"
  704.  
  705. LIB *
  706. CInit(segment)
  707. {
  708.     extern long SysBase;
  709.     extern long DOSBase;
  710.  
  711.     SysBase = *(long *)4;
  712.     DOSBase = OpenLibrary("dos.library", 0);
  713.     if (DOSBase == NULL)
  714.     return(NULL);
  715.     DResBase = Lib = MakeLibrary(LibVectors,NULL,NULL,sizeof(LIB),NULL);
  716.     Lib->lib_Node.ln_Type = NT_LIBRARY;
  717.     Lib->lib_Node.ln_Name = Libname;
  718.     Lib->lib_Flags = LIBF_CHANGED|LIBF_SUMUSED;
  719.     Lib->lib_Version  = VERSION;
  720.     Lib->lib_Revision = REVISION;
  721.     Lib->lib_IdString = (APTR)Libid;
  722.     Seglist = segment;
  723.     AddLibrary(Lib);
  724.     return(Lib);
  725. }
  726.  
  727. /*
  728.  *    Open is given the library pointer and the version request.  Either
  729.  *    return the library pointer or NULL.  Remove the DELAYED-EXPUNGE flag.
  730.  *    Exec has Forbid() for us during the call.
  731.  */
  732.  
  733. LIB *
  734. LibOpen(lib,version)
  735. LIB *lib;
  736. {
  737.     ++lib->lib_OpenCnt;
  738.     lib->lib_Flags &= ~LIBF_DELEXP;
  739.     return(lib);
  740. }
  741.  
  742. /*
  743.  *    Close is given the library pointer and the version request.  Be sure
  744.  *    not to decrement the open count if already zero.    If the open count
  745.  *    is or becomes zero AND there is a LIBF_DELEXP, we expunge the library
  746.  *    and return the seglist.  Otherwise we return NULL.
  747.  *
  748.  *    Note that this routine never sets LIBF_DELEXP on its own.
  749.  *
  750.  *    Exec has Forbid() for us during the call.
  751.  */
  752.  
  753. LibClose(lib)
  754. LIB *lib;
  755. {
  756.     if (lib->lib_OpenCnt && --lib->lib_OpenCnt)
  757.     return(NULL);
  758.     if (lib->lib_Flags & LIBF_DELEXP)
  759.     return(LibExpunge(lib));
  760.     return(NULL);
  761. }
  762.  
  763. /*
  764.  *    We expunge the library and return the Seglist ONLY if the open count
  765.  *    is zero.    If the open count is not zero we set the DELAYED-EXPUNGE
  766.  *    flag and return NULL.
  767.  *
  768.  *    Exec has Forbid() for us during the call.  NOTE ALSO that Expunge
  769.  *    might be called from the memory allocator and thus we CANNOT DO A
  770.  *    Wait() or otherwise take a long time to complete (straight from RKM).
  771.  *
  772.  *    Apparently RemLibrary(lib) calls our expunge routine and would
  773.  *    therefore freeze if we called it ourselves.  As far as I can tell
  774.  *    from RKM, LibExpunge(lib) must remove the library itself as shown
  775.  *    below.
  776.  */
  777.  
  778. LibExpunge(lib)
  779. LIB *lib;
  780. {
  781.     extern long DOSBase;
  782.  
  783.     if (lib->lib_OpenCnt) {
  784.     lib->lib_Flags |= LIBF_DELEXP;
  785.     return(NULL);
  786.     }
  787.     if (DOSBase) {
  788.     CloseLibrary(DOSBase);
  789.     DOSBase = NULL;
  790.     }
  791.     Remove(lib);
  792.     FreeMem((char *)lib-lib->lib_NegSize, lib->lib_NegSize+lib->lib_PosSize);
  793.     return(Seglist);
  794. }
  795.  
  796. \Rogue\Monster\
  797. else
  798.   echo "will not over write core/library.c"
  799. fi
  800. if [ `wc -c core/library.c | awk '{printf $1}'` -ne 4923 ]
  801. then
  802. echo `wc -c core/library.c | awk '{print "Got " $1 ", Expected " 4923}'`
  803. fi
  804. if `test ! -s libref.c`
  805. then
  806. echo "writing libref.c"
  807. cat > libref.c << '\Rogue\Monster\'
  808.  
  809. /*
  810.  *  LIBREF.C
  811.  *
  812.  *  LIBREF [cmdfile]
  813.  *  (default func.def)
  814.  */
  815.  
  816. #include <stdio.h>
  817. #include <fcntl.h>
  818. #include <local/typedefs.h>
  819.  
  820. #define FLIST    struct _FLIST
  821.  
  822. FLIST {
  823.     MNODE   Node;
  824.     uword   RegMask;
  825.     uword   IsAsm;
  826.     char    FName[64];
  827. };
  828.  
  829. extern char *MToS();
  830.  
  831. char LibGlob[64] = { "SomeUnknownLibBase" };
  832. char MName[128] = { "ram:MakeLib.c" };
  833. char LName[128] = { "ram:LinkTag.asm" };
  834. char TName[128] = { "ram:LibTag.asm" };
  835. char LibName[128] = { "ram:Lib.lib" };
  836. MLIST FBase;
  837.  
  838. main(ac,av)
  839. char *av[];
  840. {
  841.     FILE *fi;
  842.     char *file = "func.def";
  843.     char buf[128];
  844.  
  845.     puts("LIBREF V1.00 Sept 1988, (c)Copyright 1988 Matthew Dillon, All Rights Reserved");
  846.     puts("  source/executable Freely distributable for non-profit only.  May be USED");
  847.     puts("  in-house to generate commercial libraries.");
  848.  
  849.     NewList(&FBase);
  850.     if (ac == 2)
  851.     file = av[1];
  852.     fi = fopen(file, "r");
  853.     if (!fi) {
  854.     printf("%s not found\n", file);
  855.     puts("LIBREF [cmdfile]");
  856.     exit(1);
  857.     }
  858.     while (fgets(buf, sizeof(buf), fi)) {
  859.     buf[strlen(buf)-1] = 0;
  860.     if (!buf[0] || buf[0] == ';')
  861.         continue;
  862.     switch((buf[0]<<8)|buf[1]) {
  863.     case '1=':
  864.         sscanf(buf+2, "%s", MName);
  865.         break;
  866.     case '2=':
  867.         sscanf(buf+2, "%s", LName);
  868.         break;
  869.     case '3=':
  870.         sscanf(buf+2, "%s", TName);
  871.         break;
  872.     case '4=':
  873.         sscanf(buf+2, "%s", LibGlob);
  874.         break;
  875.     case '5=':
  876.         sscanf(buf+2, "%s", LibName);
  877.         break;
  878.     case '6=':
  879.     case '7=':
  880.     case '8=':
  881.     case '9=':
  882.         break;
  883.     default:
  884.         scanfile(buf, buf, sizeof(buf));
  885.         break;
  886.     }
  887.     }
  888.     fclose(fi);
  889.     {
  890.     FILE *fi = fopen(MName, "w");
  891.     if (!fi) {
  892.         printf("Unable to open %s for write\n", MName);
  893.         exit(-1);
  894.     }
  895.     GenerateMakeLib(fi);
  896.     fclose(fi);
  897.     fi = fopen(TName, "w");
  898.     if (!fi) {
  899.         printf("Unable to open %s for write\n", MName);
  900.         exit(-1);
  901.     }
  902.     GenerateTags(fi);
  903.     fclose(fi);
  904.     GenerateLinkLib(LName, strlen(LName));
  905.     }
  906. }
  907.  
  908. /*
  909.  * scan file for functions
  910.  *
  911.  *  *FUNC=NAME REGS     (C, assembly tag entry, add extra _)
  912.  *  ;FUNC=NAME REGS     (assembly, direct entry)
  913.  *         D0-2/A0/A1/A2 ...
  914.  *         REGISTERS ALWAYS LOADED D0-D7,A0-A7    (A6,A7 cannot be used)
  915.  *
  916.  *  starting within the first 16 lines of the file.
  917.  */
  918.  
  919. scanfile(file, buf, bufsize)
  920. char *file;
  921. char *buf;
  922. long bufsize;
  923. {
  924.     FILE *fi;
  925.     short i;
  926.  
  927.     fi = fopen(file, "r");
  928.     if (!fi) {
  929.     printf("Unable to open file %s\n", file);
  930.     return(-1);
  931.     }
  932.     for (i = 0; i < 16; ++i) {
  933.     short isasm;
  934.     short j;
  935.     if (fgets(buf, bufsize, fi) == NULL)
  936.         return(0);
  937.     for (j = 0; buf[j] == ' ' || buf[j] == 9; ++j);
  938.     isasm = (buf[j] == ';' || buf[j] == 'A');
  939.     ++j;
  940.     if (strncmp(buf+j, "FUNC=", 5) == 0) {
  941.         i = 0;
  942.         AddFunction(buf+j+5, isasm);
  943.     }
  944.     }
  945.     fclose(fi);
  946. }
  947.  
  948. /*
  949.  *  FuncName    Regs    (NULL SPECIAL)
  950.  */
  951.  
  952. AddFunction(buf, isasm)
  953. char *buf;
  954. {
  955.     char fname[64];
  956.     char regs[64];
  957.     uword regmask = 0;       /*  A7-A0,D7-D0 */
  958.  
  959.     if (sscanf(buf, "%s %s", fname, regs) != 2) {
  960.     printf("Argument Error: %s\n", buf);
  961.     return(-1);
  962.     }
  963.     if (strcmp(regs, "-") == 0)
  964.     regs[0] = 0;
  965.     {
  966.     register short i;
  967.     register short s, e;
  968.     for (i = 0; regs[i]; ) {
  969.         s = e = regs[i+1] - '0';
  970.         if (s < 0 || s > 7)
  971.         goto fail;
  972.         switch(regs[i]) {
  973.         case 'A':
  974.         s += 8;
  975.         e += 8;
  976.         i += 2;
  977.         if (regs[i] == '-') {
  978.             if (regs[i+1] != 'A')
  979.             goto fail;
  980.             e = regs[i+2] - '0';
  981.             if (e < 0 || e > 7)
  982.             goto fail;
  983.             e += 8;
  984.             i += 3;
  985.         }
  986.         break;
  987.         case 'D':
  988.         i += 2;
  989.         if (regs[i] == '-') {
  990.             if (regs[i+1] != 'D')
  991.             goto fail;
  992.             e = regs[i+2] - '0';
  993.             if (e < 0 || e > 7)
  994.             goto fail;
  995.             i += 3;
  996.         }
  997.         break;
  998.         default:
  999.         goto fail;
  1000.         }
  1001.         while (s <= e) {
  1002.         regmask |= 1 << s;
  1003.         ++s;
  1004.         }
  1005.         if (regs[i]) {
  1006.         if (regs[i] != '/')
  1007.             goto fail;
  1008.         ++i;
  1009.         }
  1010.     }
  1011.     }
  1012.     /*
  1013.     printf("Function: %-10s Regs: %04x  Asm: %d\n", fname, regmask, isasm);
  1014.     */
  1015.     {
  1016.     register FLIST *fl = malloc(sizeof(FLIST));
  1017.     if (fl) {
  1018.         fl->RegMask = regmask;
  1019.         fl->IsAsm    = isasm;
  1020.         if (strcmp(fname, "NULL") == 0)
  1021.         fl->FName[0] = 0;
  1022.         else
  1023.         strcpy(fl->FName, fname);
  1024.         AddTail(&FBase, fl);
  1025.     }
  1026.     }
  1027.     return(0);
  1028. fail:
  1029.     printf("Bad Register Spec: %s\n", buf);
  1030.     return(-1);
  1031. }
  1032.  
  1033. GenerateMakeLib(fi)
  1034. FILE *fi;
  1035. {
  1036.     register FLIST *fl;
  1037.     short i;
  1038.  
  1039.     fprintf(fi, "\n/*\n * Machine Generated Library Vectors\n */\n\n");
  1040.     fprintf(fi, "#ifndef NULL\n#define NULL 0L\n#endif\n\n");
  1041.     fprintf(fi, "extern long _LibOpen(), _LibClose(), _LibExpunge();\n");
  1042.     for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
  1043.     if (fl->FName[0]) {
  1044.         if (fl->IsAsm) {    /*  If assembly, direct reference   */
  1045.         fprintf(fi, "extern long l%s();\n", fl->FName);
  1046.         } else {        /*  If not, reference to tag        */
  1047.         fprintf(fi, "extern long _l%s();\n", fl->FName);
  1048.         }
  1049.     }
  1050.     }
  1051.  
  1052.     fprintf(fi, "\n\n/*\n * -30-6*X\n */\n\n");
  1053.     fprintf(fi, "long (*LibVectors[])() = {\n");
  1054.     fprintf(fi, "    _LibOpen, _LibClose, _LibExpunge, NULL,\n\n");
  1055.     for (i = 0, fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
  1056.     if (fl->FName[0]) {
  1057.         if (fl->IsAsm)
  1058.         fprintf(fi, "    l%-16s,    /*  %3ld  %-20s  */\n", fl->FName, -30-6*i, MToS(fl->RegMask));
  1059.         else
  1060.         fprintf(fi, "    _l%-15s,    /*  %3ld  %-20s  */\n", fl->FName, -30-6*i, MToS(fl->RegMask));
  1061.     } else {
  1062.         fprintf(fi, "    NULL,\n");
  1063.     }
  1064.     ++i;
  1065.     }
  1066.     fprintf(fi, "    (long (*)())-1\n};\n\n");
  1067. }
  1068.  
  1069. GenerateTags(fi)
  1070. FILE *fi;
  1071. {
  1072.     register FLIST *fl;
  1073.  
  1074.     fprintf(fi, "\n");
  1075.     fprintf(fi, "\t; Machine Generated File\n");
  1076.     fprintf(fi, "\t; Tags for library routines which are in C\n\n");
  1077.     fprintf(fi, "\tFAR\tDATA\n\n");
  1078.     for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
  1079.     uword mask;
  1080.     if (fl->IsAsm || !fl->FName[0])
  1081.         continue;
  1082.     fprintf(fi, "\n");
  1083.     fprintf(fi, "\t\tpublic _l%s\n\t\tpublic __l%s\n\n", fl->FName, fl->FName);
  1084.     fprintf(fi, "__l%s:\n", fl->FName);
  1085.  
  1086.     /*
  1087.      *  Save the set D2/D3/A6, but don't bother saving D2 or
  1088.      *  D2 and D3 if passed as arguments.
  1089.      */
  1090.  
  1091.     mask = 0x400C;
  1092.     MoveToStack(fi, mask);          /*  Save some args  */
  1093.     MoveToStack(fi, fl->RegMask);   /*  Push some args  */
  1094.     fprintf(fi, "\t\tbsr\t_l%s\n", fl->FName);
  1095.     PopStack(fi, fl->RegMask);
  1096.     MoveFromStack(fi, mask);
  1097.     fprintf(fi,"\t\trts\n");
  1098.     }
  1099. }
  1100.  
  1101.  
  1102. /*
  1103.  *  Generate the link library.    Create N output modules for
  1104.  *  each function reference by appending a number to the name
  1105.  */
  1106.  
  1107. GenerateLinkLib(dir, dirlen)
  1108. char *dir;
  1109. short dirlen;
  1110. {
  1111.     char tmp[128];
  1112.     short i, nobj, nj;
  1113.     FILE *fi;
  1114.     FILE *fi2;
  1115.     register FLIST *fl;
  1116.     register short off;
  1117.  
  1118.     strcpy(dir+dirlen, "Makefile");
  1119.     fi = fopen(dir, "w");
  1120.     if (!fi)
  1121.     goto fail;
  1122.     strcpy(dir+dirlen, "Ordin");
  1123.     fi2 = fopen(dir, "w");
  1124.     if (!fi2)
  1125.     goto fail;
  1126.  
  1127.     fputs("\nAFLAGS = -D\n\n", fi);
  1128.  
  1129.     nj = 0;
  1130.     nobj = 1;
  1131.     for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
  1132.     if (!fl->FName[0])
  1133.         continue;
  1134.     fprintf(fi2, "%s.o\n", fl->FName);
  1135.     if (nj == 0)
  1136.         fprintf(fi, "OBJ%d = ", nobj);
  1137.     fprintf(fi, "%s.o ", fl->FName);
  1138.     nj += strlen(fl->FName) + 3;
  1139.     if (nj > 70) {
  1140.         fprintf(fi, "\n");
  1141.         nj = 0;
  1142.         ++nobj;
  1143.     }
  1144.     }
  1145.     fprintf(fi2, "lvo.o\n");
  1146.     if (nj == 0)
  1147.     fprintf(fi, "OBJ%d = ", nobj);
  1148.     fprintf(fi, "lvo.o\n");
  1149.     fclose(fi2);
  1150.     fprintf(fi, "\nall:\t");
  1151.     for (i = 1; i <= nobj; ++i) {
  1152.     fprintf(fi, "$(OBJ%d) ", i);
  1153.     }
  1154.     fprintf(fi, "\n");
  1155.     fprintf(fi, "\tord %s ", dir);
  1156.     strcpy(dir+dirlen, "Ordout");
  1157.     fprintf(fi, "\t%s\n", dir);
  1158.     fprintf(fi, "\t-Delete %s\n", LibName);
  1159.     fprintf(fi, "\tlb %s -f %s\n", LibName, dir);
  1160.  
  1161.     strcpy(dir+dirlen, "lvo.asm");
  1162.  
  1163.  
  1164.     fclose(fi);
  1165.     fi = fopen(dir, "w");
  1166.     if (!fi)
  1167.     goto fail;
  1168.     for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
  1169.     if (fl->FName[0])
  1170.         fprintf(fi, "\t\tpublic\t_LVO%s\n", fl->FName);
  1171.     }
  1172.     for (off = -30, fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
  1173.     if (!fl->FName[0]) {
  1174.         off -= 6;
  1175.         continue;
  1176.     }
  1177.     sprintf(tmp, "_LVO%s", fl->FName);
  1178.     fprintf(fi, "%-24s\tequ\t%d\n", tmp, off);
  1179.     off -= 6;
  1180.     }
  1181.     fclose(fi);
  1182.  
  1183.     for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
  1184.     if (!fl->FName[0])
  1185.         continue;
  1186.     strcpy(dir+dirlen, "TEMP");
  1187.     strcpy(tmp, dir);
  1188.  
  1189.     strcpy(dir+dirlen, fl->FName);
  1190.     strcat(dir+dirlen, ".asm");
  1191.     fi = fopen(tmp, "w");
  1192.     if (!fi)
  1193.         goto fail;
  1194.  
  1195.     fprintf(fi,"\n; Machine Generated Link Tag\n\n");
  1196.     fprintf(fi,"\t\tFAR\tDATA\n");
  1197.     fprintf(fi,"\t\tpublic\t_LVO%s\n", fl->FName);
  1198.     fprintf(fi,"\t\tpublic\t_%s\n", LibGlob);
  1199.     fprintf(fi,"\t\tpublic\t_%s\n\n", fl->FName);
  1200.     fprintf(fi,"_%s:\n", fl->FName);
  1201.  
  1202.     /*
  1203.      *  Generate linker tag to assembly.  If neither A0 or A1 is
  1204.      *  used as an argument, use one as the link register, else
  1205.      *  save A6 and use that.
  1206.      *
  1207.      *  If A2-A6 (inc A6 above), D2-D6 are required to hold
  1208.      *  parameters, they are saved before the call, restored
  1209.      *  after.   If they are not required to hold any parameters,
  1210.      *  a JMP is issued instead of a JSR.
  1211.      */
  1212.  
  1213.     {
  1214.         uword argmask = fl->RegMask;
  1215.         uword savmask = fl->RegMask;
  1216.         short areg = 6;
  1217.         if (!(argmask & 0x0100))   /*  A0 not used */
  1218.         areg = 0;
  1219.         if (!(argmask & 0x0200))   /*  A1 not used */
  1220.         areg = 1;
  1221.         savmask |= 1 << (areg+8);  /*  Add register usage  */
  1222.         MoveToStack(fi, savmask & 0xFCFC);                          /*  save some regs      */
  1223.         LoadFromStack(fi, argmask, 4+Offset(argmask & 0xFCFC));     /*  load params         */
  1224.         fprintf(fi,"\t\tmove.l\t_%s,A%d\n", LibGlob, areg);
  1225.         if (savmask & 0xFCFC) {
  1226.         fprintf(fi, "\t\tjsr\t_LVO%s(A%d)\n", fl->FName, areg);
  1227.         MoveFromStack(fi, savmask & 0xFCFC);                    /*  restore some regs   */
  1228.         fprintf(fi,"\t\trts\n");
  1229.         } else {
  1230.         fprintf(fi, "\t\tjmp\t_LVO%s(A%d)\n", fl->FName, areg);
  1231.         }
  1232.     }
  1233.     fclose(fi);
  1234.     if (cmp_file(tmp, dir) == 0) {  /*  update only if changed  */
  1235.         DeleteFile(dir);
  1236.         Rename(tmp, dir);
  1237.     }
  1238.     }
  1239.     return(0);
  1240. fail:
  1241.     printf("Unable to open %s\n", dir);
  1242.     return(-1);
  1243. }
  1244.  
  1245. char *
  1246. MToS(mask)
  1247. register uword mask;
  1248. {
  1249.     register short i;
  1250.     register short j = 0;
  1251.     static char buf[64];
  1252.  
  1253.     for (i = 0; i < 8; ++i, mask >>= 1) {
  1254.     if (mask & 1) {
  1255.         if (j)
  1256.         buf[j++] = '/';
  1257.         buf[j++] = 'D';
  1258.         buf[j++] = i + '0';
  1259.     }
  1260.     }
  1261.     for (i = 0; i < 8; ++i, mask >>= 1) {
  1262.     if (mask & 1) {
  1263.         if (j)
  1264.         buf[j++] = '/';
  1265.         buf[j++] = 'A';
  1266.         buf[j++] = i + '0';
  1267.     }
  1268.     }
  1269.     buf[j++] = 0;
  1270.     return(buf);
  1271. }
  1272.  
  1273.  
  1274. MoveToStack(fi, mask)
  1275. FILE *fi;
  1276. {
  1277.     char *str = MToS(mask);
  1278.     if (!str[0])
  1279.     return(0);
  1280.     if (!str[2]) {
  1281.     fprintf(fi, "\t\tmove.l\t%s,-(sp)\n", str);
  1282.     } else {
  1283.     fprintf(fi, "\t\tmovem.l\t%s,-(sp)\n", str);
  1284.     }
  1285. }
  1286.  
  1287. MoveFromStack(fi, mask)
  1288. FILE *fi;
  1289. uword mask;
  1290. {
  1291.     char *str = MToS(mask);
  1292.  
  1293.     if (!str[0])
  1294.     return(0);
  1295.     if (!str[2])
  1296.     fprintf(fi, "\t\tmove.l\t(sp)+,%s\n", str);
  1297.     else
  1298.     fprintf(fi, "\t\tmovem.l\t(sp)+,%s\n", str);
  1299. }
  1300.  
  1301. LoadFromStack(fi, mask, offset)
  1302. {
  1303.     char *str = MToS(mask);
  1304.  
  1305.     if (!str[0])
  1306.     return(0);
  1307.     if (!str[2])
  1308.     fprintf(fi, "\t\tmove.l\t%d(sp),%s\n", offset, str);
  1309.     else
  1310.     fprintf(fi, "\t\tmovem.l\t%d(sp),%s\n", offset, str);
  1311. }
  1312.  
  1313.  
  1314. PopStack(fi, mask)
  1315. FILE *fi;
  1316. uword mask;
  1317. {
  1318.     register short j;
  1319.     if (j = Offset(mask)) {
  1320.     if (j > 8)
  1321.         fprintf(fi,"\t\tadd.w\t#%d,A7\n", j);
  1322.     else
  1323.         fprintf(fi,"\t\taddq.l\t#%d,A7\n", j);
  1324.     }
  1325. }
  1326.  
  1327. Offset(mask)
  1328. uword mask;
  1329. {
  1330.     register short i, j;
  1331.     for (i = j = 0; i < 16; ++i) {
  1332.     if (mask & (1 << i))
  1333.         ++j;
  1334.     }
  1335.     return(j*4);
  1336. }
  1337.  
  1338. cmp_file(name1, name2)
  1339. char *name1;
  1340. char *name2;
  1341. {
  1342.     short i, fd1, fd2;
  1343.     static char buf1[1024];
  1344.     static char buf2[1024];
  1345.  
  1346.     fd1 = open(name1, O_RDONLY);
  1347.     if (fd1 < 0)
  1348.     return(0);
  1349.     fd2 = open(name2, O_RDONLY);
  1350.     if (fd2 < 0) {
  1351.     close(fd1);
  1352.     return(0);
  1353.     }
  1354.     while ((i = read(fd1, buf1, sizeof(buf1))) > 0) {
  1355.     if (read(fd2, buf2, i) != i)
  1356.         goto fail;
  1357.     if (bcmp(buf1, buf2, i) == 0)
  1358.         goto fail;
  1359.     }
  1360.     if (read(fd2, buf2, 1) != 0)
  1361.     goto fail;
  1362.     close(fd1);
  1363.     close(fd2);
  1364.     return(1);
  1365. fail:
  1366.     close(fd1);
  1367.     close(fd2);
  1368.     return(0);
  1369. }
  1370.  
  1371. \Rogue\Monster\
  1372. else
  1373.   echo "will not over write libref.c"
  1374. fi
  1375. if [ `wc -c libref.c | awk '{printf $1}'` -ne 12306 ]
  1376. then
  1377. echo `wc -c libref.c | awk '{print "Got " $1 ", Expected " 12306}'`
  1378. fi
  1379. echo "Finished archive 3 of 3"
  1380. # if you want to concatenate archives, remove anything after this line
  1381. exit
  1382. -- 
  1383. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  1384. Have five nice days.
  1385.